package com.ljm.file.record.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ljm.common.page.PageDto;
import com.ljm.file.properties.BucketType;
import com.ljm.file.record.entity.SysFile;
import com.ljm.file.record.mapper.SysFileMapper;
import com.ljm.file.record.service.ISysFileService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ljm.file.record.api.SysFileApi;
import com.ljm.file.record.dto.SysFileDto;
import com.ljm.file.recycle.dto.SysFileRecycleDto;
import com.ljm.file.recycle.service.ISysFileRecycleService;
import com.ljm.file.service.FileService;
import com.ljm.security.util.UserUtil;
import com.ljm.service.BaseServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
    *  平台文件信息服务实现类
    * </p>
 *
 * @author HuamingChen
 * @since 2020-09-28
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class SysFileServiceImpl extends BaseServiceImpl<SysFileMapper, SysFile>
        implements ISysFileService, SysFileApi {

    @Resource
    private FileService fileService;
    @Resource
    private ISysFileRecycleService sysFileRecycleService;

    @Override
    public void saveFileRecord(SysFileDto dto) {
        SysFile po=new SysFile();
        mapperFacade.map(dto,po);
        if (dto.getId()==null) {
            po.setCreateTime(LocalDateTime.now());
            po.setCreater(UserUtil.getLoginName());
            po.setIsDelete(false);
        }
        this.saveOrUpdate(po);
    }

    @Override
    public SysFileDto getFileInfoByOssFileId(String ossFileId) {
        SysFile po = this.getOne(new LambdaQueryWrapper<SysFile>().eq(SysFile::getOssFileId, ossFileId));
        if(po==null){
            return null;
        }else{
            SysFileDto dto=new SysFileDto();
            mapperFacade.map(po,dto);
            return dto;
        }

    }

    @Override
    public void deleteFile(String ossFileId) {
        SysFile fileInfo =getFileEntityByOssFileId(ossFileId);
        String objFullName=fileInfo.getOssFileId()+"."+fileInfo.getFileSuffix();
        fileService.deleteFile(fileInfo.getFileType()?BucketType.publicBucket:BucketType.secrecyBucket,fileInfo.getStoragePath(),objFullName);
        this.removeById(fileInfo.getId());
        //数据迁移到回收站表
        fileInfo.setIsDelete(true);
        sysFileRecycleService.addFileRecycle(fileInfo);
    }

    @Override
    public void asynDeleteFile(String ossFileId) {
        SysFile po =getFileEntityByOssFileId(ossFileId);
        po.setIsDelete(false);
        this.removeById(po.getId());
        //数据迁移到回收站表
        sysFileRecycleService.addFileRecycle(po);
    }

    @Override
    public void recoveryFileByAsynDelete(String ossFileId) {
        //在回收站恢复文件
        SysFile fileInfo = sysFileRecycleService.recoveryFile(ossFileId);
        fileInfo.setIsDelete(false);
        this.save(fileInfo);
    }

    private SysFile getFileEntityByOssFileId(String ossFileId){
        SysFile po = this.getOne(new LambdaQueryWrapper<SysFile>().eq(SysFile::getOssFileId, ossFileId));
        if(po==null){
            throw new RuntimeException("无该文件,请确认");
        }
        return po;
    }

    @Override
    public PageDto<SysFileDto> getFileRecordByPage(SysFileDto dto) {
        PageDto<SysFileDto> pageDto=new PageDto<>(dto.getPageNo(),dto.getPageSize());
        IPage<SysFile> page=new Page<>(dto.getPageNo(),dto.getPageSize());
        LambdaUpdateWrapper<SysFile> wrapper=new LambdaUpdateWrapper<>();
        if(StringUtils.isNotEmpty(dto.getFdSys())){
            wrapper.eq(SysFile::getFdSys,dto.getFdSys());
        }
        if(StringUtils.isNotEmpty(dto.getFdModule())){
            wrapper.eq(SysFile::getFdModule,dto.getFdModule());
        }
        if(StringUtils.isNotEmpty(dto.getFdSectionId())){
            wrapper.eq(SysFile::getFdSectionId,dto.getFdSectionId());
        }
        if(StringUtils.isNotEmpty(dto.getStoragePath())){
            wrapper.likeRight(SysFile::getStoragePath,dto.getStoragePath());
        }
        if(StringUtils.isNotEmpty(dto.getOssFileId())){
            wrapper.eq(SysFile::getOssFileId,dto.getOssFileId());
        }
        if(dto.getFileType()!=null){
            wrapper.eq(SysFile::getFileType,dto.getFileType());
        }
        page = this.page(page, wrapper);
        if(page.getTotal()>0){
            pageDto.setTotal(page.getTotal());
            pageDto.setRecords(mapperFacade.mapAsList(page.getRecords(),SysFileDto.class));
        }
        return pageDto;
    }

    @Override
    public SysFileRecycleDto getFileInfoInRecycle(String ossFileId) {
        return sysFileRecycleService.getByOssFileId(ossFileId);
    }

    @Override
    public void confirmFile(List<String> ossFileIds) {
        this.update(new LambdaUpdateWrapper<SysFile>().in(SysFile::getOssFileId,ossFileIds).set(SysFile::getFdConfirmed,true));
    }

    @Override
    public Map<Class, Class> classMap() {
        Map<Class,Class> map=new HashMap<>(1);
        map.put(SysFile.class,SysFileDto.class);
        return map;
    }
}
